home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus Special 25 / AMIGAplus Sonderheft 25 (2000)(Falke)(DE)(Track 1 of 4)[!].iso / PublicDomain / Anwendungen / Altabber / src / Altabber.c next >
C/C++ Source or Header  |  1999-04-01  |  25KB  |  926 lines

  1. /*  Altabber, n. He who performs an `Alt-Tab' action.
  2. **
  3. **  Version 1.5 (1.4.99) © Mfc.
  4. **
  5. **  Compile with DICE:
  6. **      dcc -mi -mRR -pi Altabber.c NewReadArgs.c
  7. **
  8. **  The "fixed-keys" version of Altabber (without argument/tooltypes parsing)
  9. **  can be obtained with:
  10. **      dcc -mi -mRR -DFIXEDKEYS -pi Altabber.c
  11. **
  12. **  To enable debugging output, simply add "-DDEBUG"
  13. **
  14. */
  15.  
  16.  
  17. #include "Altabber.h"
  18. #ifndef FIXEDKEYS
  19. #include <NewReadArgs.h>
  20. #endif
  21.  
  22. /// Defines
  23.  
  24. /* Messages we will receive from the Cx filter: */
  25. #define WINTAB      1   /* Cycle thru windows */
  26. #define SCRTAB      2   /* Cycle thru screens */
  27. #define UPSTROKE    8   /* Select this item */
  28.  
  29. /* Max string lengths: */
  30. #define MAX_TITLE_LEN   80
  31. #define MAX_HOTKEY_LEN  40
  32.  
  33. /* Some macros: */
  34. #define CURRENTLY_ACTIVE_SCR    IntuitionBase->ActiveScreen
  35. #define CURRENTLY_ACTIVE_WIN    IntuitionBase->ActiveWindow
  36. #define FIRST_AVAILABLE_SCR     IntuitionBase->FirstScreen
  37. #define FIRST_AVAILABLE_WIN     IntuitionBase->ActiveScreen->FirstWindow
  38.  
  39. /* Pretty obvious :-) */
  40. #define JAM1 0
  41. #define JAM2 1
  42.  
  43. /* This is a clearly impossible hotkey */
  44. #define DUMMY_KEY   "Ctrl LAmiga RAmiga NumPad *"
  45.  
  46. /* A couple of largely used macros: */
  47. #define xalloc(s)   AllocVec(s, 0)
  48. #define xfree(a)    FreeVec(a)
  49.  
  50. #ifdef DEBUG
  51. #define D(x)    x
  52. #else
  53. #define D(x)
  54. #endif
  55.  
  56. #define TEMPLATE    "WQ=WIN_QUAL/K,WK=WIN_KEY/K," \
  57.                     "SQ=SCR_QUAL/K,SK=SCR_KEY/K," \
  58.                     "CX_PRIORITY/N/K,"      \
  59.                     "COLOR1/N/K,COLOR2/N/K,"\
  60.                     "AA=AUTOACTIVATE/S" /* Not yet fully functional! */
  61. ///
  62.  
  63. /// Globals
  64.  
  65. /* The options (either CLI parameters or icon ToolTypes) */
  66. /* are stored in the Opt struct. Some defaults are given here: */
  67. const int def_pri = -5;
  68. const int def_color1 = 1;
  69. const int def_color2 = 2;
  70.  
  71. struct {
  72.     STRPTR win_qual, win_key;
  73.     STRPTR scr_qual, scr_key;
  74.     int *pri;
  75.     int *color1, *color2;
  76.     int aa; /* Not yet fully functional! */
  77. } Opt = {
  78.     "LAmiga", "Tab",
  79.     "LAmiga", "Shift Tab",
  80.     &def_pri,
  81.     &def_color1, &def_color2,
  82.     0       /* Not yet fully functional! */
  83. };
  84.  
  85. /* These are extern since we let the compiler care for */
  86. /* opening library, replying WB, etc. */
  87. extern struct IntuitionBase *IntuitionBase;
  88. extern struct WBStartup *_WBMsg;
  89.  
  90. /* Has our window been opened? */
  91. int Win_open = 0;
  92. int Scr_open = 0;
  93.  
  94. /* Each item (either scr or win) is stored in a struct */
  95. /* like this. Multiple records are then linked together */
  96. /* in a single chain. */
  97.  
  98. struct record {
  99.     void            *id;
  100.     unsigned char   title[MAX_TITLE_LEN];
  101.     int             len;
  102.     int             width;
  103.     struct record   *next;
  104. };
  105.  
  106. struct record *First_item;      /* Head of the chain */
  107. struct record *Special_item;    /* Some magic stuff usad by the OMM */
  108. struct record *Displayed_item;  /* The currently displayed item */
  109. struct record *Active_item;     /* The item which was active when the user */
  110.                                 /* pressed the hotkey the first time */
  111.  
  112. /* Gfx Globals: all the global variable which are related to gfx */
  113. /* (window, rastport, fonts, etc.) are placed in a single global struct */
  114. struct {
  115.     struct Window   *win;
  116.     struct RastPort *rp;
  117.     struct TextFont *font;
  118.     int font_height;
  119.     int font_baseline;
  120.     int max_width;
  121.     int top_corner, left_corner;
  122. } GG = {NULL};
  123.  
  124. /* OMM (Olivier's Memory Method) */
  125. void *Last_active_win = NULL;
  126. void *Last_active_scr = NULL;
  127.  
  128. struct MsgPort  *mp;    /* the port where we will receive all the msgs */
  129. ULONG   Sigbits;        /* signals we will wait for */
  130.  
  131. /* Every Cx must have an Object called a broker: */
  132. CxObj           *Broker;
  133.  
  134. /* The special filters used to know when the user releases the qualifier key. */
  135. /* They can't be "normal" hotkeys as they imply "upstroke", which the Cx */
  136. /* interface doen't recognize. */
  137.             /*  magic       class        code  cmask qual qmask synonyms*/
  138. IX scr_ix = { IX_VERSION, IECLASS_RAWKEY,  0, 0xffff,  0,   0,   0 };
  139. IX win_ix = { IX_VERSION, IECLASS_RAWKEY,  0, 0xffff,  0,   0,   0 };
  140.  
  141.  
  142.  
  143. ///
  144.  
  145. /// Prototypes
  146.  
  147. int open_window(void);
  148. void close_window(void);
  149. void display_next(void);
  150.  
  151. int create_scrlist(void);
  152. int create_winlist(void);
  153. void raise_scr(void);
  154. void raise_win(void);
  155. void dispose_list(void);
  156.  
  157. void handle(void);
  158.  
  159. int copy_title(STRPTR, STRPTR);
  160. int qualcode(STRPTR);
  161.  
  162. CxObj *AttachFilter(STRPTR, ULONG);
  163. int ShowError(STRPTR);
  164. ///
  165.  
  166. #define BROKERVERSION "Altabber 1.5  ©1999 Mfc."
  167. static const STRPTR version = "$VER: Altabber 1.5 (1.4.99)";
  168.  
  169. /// main()
  170. /*  ¯¯¯¯¯¯
  171. */
  172.  
  173. #ifdef _DCC
  174. __stkargs
  175. #endif
  176. void _main()
  177. {
  178.     int error = 0;
  179.  
  180. #ifndef FIXEDKEYS
  181.     /* Read the arguments/tooltypes */
  182.     struct NewRDArgs nrda = {
  183.         TEMPLATE,
  184.         NULL,
  185.         NULL,
  186.         (LONG *) &Opt,
  187.         -1,
  188.         TRUE,
  189.         /* other fields = NULL */
  190.     };
  191.  
  192.     error = NewReadArgs(_WBMsg, &nrda);
  193. #endif
  194.  
  195.     if (error == 0)
  196.     {
  197.         unsigned char win_hotkey[MAX_HOTKEY_LEN];
  198.         unsigned char scr_hotkey[MAX_HOTKEY_LEN];
  199.  
  200. #ifdef DEBUG
  201.         Printf("win_qual=%s\n", Opt.win_qual);
  202.         Printf("win_key=%s\n", Opt.win_key);
  203.         Printf("scr_qual=%s\n", Opt.scr_qual);
  204.         Printf("scr_key=%s\n", Opt.scr_key);
  205.         Printf("pri=%ld\n", *Opt.pri);
  206.         Printf("color1,2=%ld,%ld\n", *Opt.color1, *Opt.color2);
  207.         Printf("aa=%ld\n", Opt.aa);
  208. #endif
  209.  
  210.         /* Try to interpret the options and to build an adequate */
  211.         /* IX filter for every qualifier */
  212.         win_ix.ix_Code = IECODE_UP_PREFIX | qualcode(Opt.win_qual);
  213.         scr_ix.ix_Code = IECODE_UP_PREFIX | qualcode(Opt.scr_qual);
  214.  
  215.         /* Build the win hotkey as the union of the "_QUAL" option */
  216.         /* and the "_KEY" option */
  217.         strcpy(win_hotkey, Opt.win_qual);
  218.         strcat(win_hotkey, " ");
  219.         strcat(win_hotkey, Opt.win_key);
  220.  
  221.         /* Build the scr hotkey as the union of the "_QUAL" option */
  222.         /* and the "_KEY" option */
  223.         strcpy(scr_hotkey, Opt.scr_qual);
  224.         strcat(scr_hotkey, " ");
  225.         strcat(scr_hotkey, Opt.scr_key);
  226.  
  227. #ifdef DEBUG
  228.         Printf("win_hotkey=|%s|\n", win_hotkey);
  229.         Printf("scr_hotkey=|%s|\n", scr_hotkey);
  230.         Printf("win_ix.ix_Code=%lx\n", win_ix.ix_Code);
  231.         Printf("scr_ix.ix_Code=%lx\n", scr_ix.ix_Code);
  232. #endif
  233.  
  234.         if (mp=CreateMsgPort())
  235.         {
  236.             /* Create the broker */
  237.             struct NewBroker nb = {
  238.                 NB_VERSION,
  239.                 "Altabber",
  240.                 BROKERVERSION,
  241.                 "Windoze-like Alt-Tab function",
  242.                 NBU_UNIQUE | NBU_NOTIFY,
  243.                 0, *Opt.pri, 0, 0
  244.             };
  245.  
  246.             nb.nb_Port = mp;
  247.             Sigbits = SIGBREAKF_CTRL_C | (1L << mp->mp_SigBit);
  248.  
  249.             if (Broker=CxBroker(&nb, &error))
  250.             {
  251.                 /* Now we start to attach things to the broker. */
  252.                 /* First of all the two filters which intercept */
  253.                 /* the Amiga+Tab and Amiga+Shift+Tab strokes */
  254.                 if (AttachFilter(win_hotkey, WINTAB) &&
  255.                     AttachFilter(scr_hotkey, SCRTAB))
  256.                 {
  257.                     /* Add the special filter which intercept */
  258.                     /* the release of the Amiga key. To do this, */
  259.                     /* first build a normal filetr with a dummy hotkey, */
  260.                     /* then replace the dummy hotkey with the actual IX */
  261.                     CxObj *x = AttachFilter(DUMMY_KEY, UPSTROKE);
  262.                     if (x)
  263.                     {
  264.                         SetFilterIX(x, &win_ix);
  265.  
  266.                         /* Do the same with the scr upstroke filter, */
  267.                         /* but only if it's different from the win one */
  268.                         if (scr_ix.ix_Code != win_ix.ix_Code)
  269.                         {
  270.                             x = AttachFilter(DUMMY_KEY, UPSTROKE);
  271.                             if (x)
  272.                                 SetFilterIX(x, &scr_ix);
  273.                         }
  274.                         if (x)
  275.                         {
  276.                             /* If everithing's ok, activate the broker */
  277.                             ActivateCxObj(Broker, 1);
  278.  
  279.